package org.zhs.common.result;;

/**
 * 返回对象实现
 */
public class Result<T> implements IResult {

    /**
     * 是否成功
     */
    private boolean success;
    /**
     * 返回编码
     */
    private int code;
    /**
     * 返回消息
     */
    private String message;
    /**
     * 返回数据
     */
    private T data;

    public Result() {
    }

    private Result(boolean success, String message, int code) {
        this.success = success;
        this.message = message;
        this.data = null;
        this.code = code;
    }

    private Result(boolean success, String message, T data, int code) {
        this.success = success;
        this.message = message;
        this.data = data;
        this.code = code;
    }


    public static <T> Result<T> success() {
        return success(BaseCodeEnum.SUCCESS);
    }

    public static <T> Result<T> success(CodeEnum codeEnum) {
        return success(codeEnum, null);
    }

    public static <T> Result<T> success(int code, String message) {
        return success(code, message, null);
    }

    public static <T> Result<T> success(String message) {
        return success(message, null);
    }

    public static <T> Result<T> success(T data) {
        return success(BaseCodeEnum.SUCCESS, data);
    }

    public static <T> Result<T> success(CodeEnum codeEnum, T data) {
        return new Result<>(true, codeEnum.getMessage(), data, codeEnum.getCode());
    }

    public static <T> Result<T> success(String message, T data) {
        return new Result<>(true, message, data, BaseCodeEnum.SUCCESS.getCode());
    }

    public static <T> Result<T> success(int code, String message, T data) {
        return new Result<>(true, message, data, code);
    }

    public static <T> Result<T> failed() {
        return failed(BaseCodeEnum.FAILED);
    }

    public static <T> Result<T> failed(String message) {
        return failed(message, null);
    }

    public static <T> Result<T> failed(CodeEnum codeEnum) {
        return failed(codeEnum, null);
    }

    public static <T> Result<T> failed(int code, String message) {
        return failed(code, message, null);
    }


    public static <T> Result<T> failed(CodeEnum codeEnum, T data) {
        return new Result<>(false, codeEnum.getMessage(), data, codeEnum.getCode());
    }

    public static <T> Result<T> failed(String message, T data) {
        return failed(BaseCodeEnum.FAILED.getCode(), message, data);
    }

    public static <T> Result<T> failed(int code, String message, T data) {
        return new Result<>(false, message, data, code);
    }

    @Override
    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    @SuppressWarnings("unchecked")
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    /**
     * 基础通用枚举
     */
    public enum BaseCodeEnum implements CodeEnum {
        /**
         * 操作成功
         */
        SUCCESS(200, "操作成功"),

        /**
         * 操作失败
         */
        FAILED(500, "操作失败"),

        /**
         * 动态Code
         */
        CODE(-1, "");
        /**
         * 响应码
         */
        private Integer code;

        /**
         * 响应信息
         */
        private String message;

        BaseCodeEnum(Integer code, String message) {
            this.code = code;
            this.message = message;
        }

        @Override
        public Integer getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        /**
         * 自定义枚举code,message
         * 注意:只能使用 BaseCodeEnum.CODE
         * BaseCodeEnum.CODE.set(int code,String message)
         *
         * @param code    code
         * @param message message
         * @return BaseCodeEnum
         */
        @Override
        public BaseCodeEnum set(int code, String message) {
            this.code = code;
            this.message = message;
            return this;
        }

        /**
         * 变更指定枚举 message
         * 任意枚举都可以使用
         * BaseCodeEnum.CODE.set(String message)
         *
         * @param message message
         * @return ResultCodeEnum
         */
        @Override
        public BaseCodeEnum set(String message) {
            BaseCodeEnum.CODE.set(this.getCode(), message);
            return BaseCodeEnum.CODE;
        }
    }

    @Override
    public String toString() {
        return "Result{" +
                "success=" + success +
                ", message='" + message + '\'' +
                ", data=" + data +
                ", code=" + code +
                '}';
    }
}
